package com.igelato.filter;

import com.alibaba.fastjson2.JSON;
import com.igelato.model.AdminUser;
import com.igelato.response.AppException;
import com.igelato.response.ErrorCodeMsgEnum;
import com.igelato.response.R;
import com.igelato.service.AdminUserService;
import com.igelato.utils.JwtToken;
import com.igelato.utils.ThreadLocalTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Description: 请求拦截器
 * @Author: wht
 * @Date: 2023-12-30
 */
@Order(1)
@Slf4j
@WebFilter(filterName = "MyFilter", urlPatterns = {"/*"})
//@Component
public class RequestFilter implements Filter {

    private AdminUserService userService;

    //路径匹配器，支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();


    @Override
    public void init(FilterConfig filterConfig) {
        ServletContext servletContext = filterConfig.getServletContext();
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        userService = webApplicationContext.getBean(AdminUserService.class);
        System.out.println("----FilterDemo01过滤器初始化----");
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        ThreadLocalTool.setCurrentTime();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

//      跨域------------------------------------
        response.setHeader("Content-Type", "application/json; charset=utf-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, PATCH, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");

//      判断本次请求是否需要处理。如果不需要处理，则直接放行---------------------
        String requestURI = request.getRequestURI();
        log.info("请求路径：" + requestURI);
        String[] urls = new String[]{"/login*", "/v2/api-docs", "/**/*swagger*/**"};
        if (check(urls, requestURI)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

//     从token中拿到userId，然后从数据库中获取用户信息，并保存到ThreadLocal中------------------------
        try {
            String token = request.getHeader("X-Token");
            Integer user_id = JwtToken.parseToken(token);
            if (user_id == null) {
                throw new AppException(ErrorCodeMsgEnum.TOKEN_ERROR);
            }
            AdminUser user = userService.getById(user_id);
            if (user == null) {
                throw new AppException(ErrorCodeMsgEnum.TOKEN_ERROR);
            }
//            把user存入ThreadLocal中
            ThreadLocalTool.setUser(user);
        } catch (Exception e) {
            response.getWriter().write(JSON.toJSONString(R.error(ErrorCodeMsgEnum.TOKEN_ERROR)));
            return;
        }


        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        log.info("耗时:" + (System.currentTimeMillis() - ThreadLocalTool.getTime()));
        log.info("请求--------------------------end");
        ThreadLocalTool.remove();
    }

    /**
     * 路径匹配，检查本次请求是否需要放行
     *
     * @param urls
     * @param requestURI
     * @return
     */
    public static boolean check(String[] urls, String requestURI) {
        for (String url : urls) {
            if (PATH_MATCHER.match(url, requestURI)) {
                return true;
            }
        }
        return false;
    }
}
